﻿/// <reference path = "Base.ts" />
namespace VantCellTypes {

    interface TagCellTypeParam {
        ClickCommand: Forguncy.Plugin.ICustomCommandObject;
        ColorList: { color: string }[];
        DefaultValue: string;
        size: string;
        theme: string;
        gutter: number;
        distinct: boolean;
        separator: string;
        allowAdd: boolean;
        addButtonSettings: AddButtonSettings;
    }

    interface AddButtonSettings {
        width: number;
        text: string;
        space: number;
    }

    interface Tag {
        key: string | number;
        label: string;
        color: string;
    }

    enum TagTheme {
        default = "default",
        plain = "plain",
        round = "round",
        mark = "mark"
    }

    export class TagCellType extends VantCellTypeBase<TagCellTypeParam> {
        public onPageLoaded(info: Forguncy.Plugin.CellTypeInfo) {
            const cellType = this.cellType;
            const { WordWrap = false } = this.CellElement.StyleInfo;
            const self = this;
            let style = null;
            if (WordWrap) {
                style = {
                    "overflow-y": "auto"
                };
            } else {
                style = {
                    "display": "flex",
                    "align-items": "center",
                    "overflow-x": "auto"
                };
            }
            $(`#${this.uId}`).css(style);
            const template = `
<van-tag
    v-for="(tag, index) in tags"
    :key="tag.key"
    :size="size"
    :color="tag.color"
    :plain="plain"
    :round="round"
    :mark="mark"
    :closeable="!readonly"
    @click="onTagClick"
    @close.stop="onTagClose"
    :style="getTagStyle(index, tags.length)"
>
{{ tag.label }}
</van-tag>
<template v-if="!readonly && allowAdd && !inputVisible">
    <van-tag
        type="primary"
        :size="size"
        :plain="plain"
        :round="round"
        :mark="mark"
        @click="showInput"
        class="van-tag-button"
        :style="{ ...buttonFieldStyle, justifyContent: 'center' }"
    >
        {{ buttonText }}
    </van-tag>
</template>
<template v-if="!readonly && allowAdd && inputVisible">
    <van-field
        ref="saveTagInput"
        v-model="inputValue"
        @blur="handleInputConfirm"
        @keyup.enter.native="handleInputConfirm"
        :style="fieldStyle"
    ></van-field>
</template>
`
                ;
            const option = {
                template,
                data() {
                    return {
                        tags: [],
                        size: cellType.size,
                        gutter: cellType.gutter,
                        plain: cellType.theme === TagTheme.plain,
                        round: cellType.theme === TagTheme.round,
                        mark: cellType.theme === TagTheme.mark,
                        readonly: false,
                        buttonText: cellType.addButtonSettings.text,
                        buttonWidth: cellType.addButtonSettings.width,
                        buttonSpace: cellType.addButtonSettings.space,
                        inputValue: "",
                        inputVisible: false,
                        allowAdd: !!cellType.allowAdd,
                        fieldHeight: "0px",
                        wordWrap: !!WordWrap
                    };
                },
                computed: {
                    buttonFieldStyle({ buttonWidth, gutter, wordWrap }) {
                        const style = {
                            width: buttonWidth + "px",
                            minWidth: buttonWidth + "px"
                        };
                        if (wordWrap) {
                            style["marginBottom"] = gutter + "px";
                        }
                        return style;
                    },
                    fieldStyle({ buttonFieldStyle, fieldHeight, wordWrap }) {
                        const style = {
                            ...buttonFieldStyle,
                            height: fieldHeight
                        };
                        if (wordWrap) {
                            style.display = "inline-flex";
                            style.verticalAlign = "top";
                        }
                        return style;
                    }
                },
                methods: {
                    getValue() {
                        return this.tags.map((tag: Tag) => tag.label).join(cellType.separator);
                    },
                    setValue(value: string) {
                        if (self.isEmpty(value)) {
                            this.tags = [];
                            return;
                        }
                        this.tags = value.split(cellType.separator).filter(tag => tag !== "");
                        if (cellType.distinct) {
                            this.tags = this.distinct(this.tags);
                        }
                        const colors = cellType.ColorList.map(color => Forguncy.ConvertToCssColor(color.color));
                        this.tags = this.tags.map((tag, index, arr) => {
                            return {
                                key: cellType.distinct ? tag : index,
                                label: tag,
                                color: colors[index % colors.length]
                            };
                        });
                    },
                    getTagStyle(index: number, length: number) {
                        const style = {
                            flex: "none",
                            marginRight: index === length - 1 ? this.buttonSpace + 'px' : this.gutter + 'px'
                        };
                        if (this.wordWrap) {
                            style["marginBottom"] = this.gutter + 'px';
                        }
                        return style;
                    },
                    onTagClick(event: PointerEvent) {
                        if (cellType.ClickCommand?.Commands?.length) {
                            const index = this.getEventIndex(event, "van-tag");
                            if (index >= 0) {
                                const initValue = {};
                                initValue[cellType.ClickCommand.ParamProperties["itemName"]] = this.tags[index].label;
                                self.executeCustomCommandObject(cellType.ClickCommand, initValue);
                            }
                        }
                    },
                    onTagClose(event: PointerEvent) {
                        const index = this.getEventIndex(event, "van-tag__close");
                        if (index >= 0) {
                            this.tags.splice(index, 1);
                            self.commitValue();
                        }
                    },
                    getEventIndex(event: PointerEvent, className: string) {
                        const clickItem = <any>event.target;

                        const items = $(`.${className}`, self.getContainer());

                        for (let i = 0; i < items.length; i++) {
                            const item = items[i];
                            if (item === clickItem) {
                                return i;
                            }
                        }
                    },
                    distinct(arr): any[] {
                        const result = [];
                        const obj = {};
                        for (const i of arr) {
                            if (obj[i]) {
                                continue;
                            }
                            obj[i] = true;
                            result.push(i);
                        }
                        return result;
                    },
                    showInput() {
                        this.inputVisible = true;
                        this.$nextTick(_ => {
                            this.$refs.saveTagInput.focus();
                        });
                    },

                    handleInputConfirm() {
                        const inputValue = this.inputValue;
                        if (inputValue) {
                            const currentValue = this.getValue();
                            this.setValue(currentValue ? currentValue + cellType.separator + inputValue : inputValue);
                            self.commitValue();
                        }
                        this.inputVisible = false;
                        this.inputValue = '';
                    },
                    setReadOnly(value) {
                        this.readonly = value;
                    }
                },

                mounted() {
                    if (this.allowAdd) {
                        this.fieldHeight = getComputedStyle($(".van-tag-button", self.getContainer())[0]).height;
                    }
                }
            };
            this.createVueApp(option);
            super.onPageLoaded(info);
        }

        public setReadOnly(value) {
            super.setReadOnly(value);
            this.refreshClickable();
        }

        refreshClickable() {
            this.getContainer()?.attr("clickable", this.clickable() ? true : "");
        }

        protected clickable(): boolean {
            const cellType = <TagCellTypeParam>this.CellElement.CellType;
            return !this.isReadOnly() || (cellType?.ClickCommand?.Commands && cellType.ClickCommand.Commands.length > 0);
        }
    }
}

Forguncy.Plugin.CellTypeHelper.registerCellType("Vant.CellTypes.Tag, Vant", VantCellTypes.TagCellType);